//
// Created by antler on 2018/12/5.
//

#include "lprefix.h"

#include <string>

#include "lua.hpp"
#include "luaext.hpp"

#include "log.h"
#include "GlobalMacros.h"

#include "Script.h"

// Script
static int script_tostring(lua_State *L) {
    lua_pushfstring(L, "class: %p", lua_topointer(L, 1));
    return 1;
}

static int script_getUserInfo(lua_State *L) {
    UserInfo userInfo;
    int err = Script::getInstance()->getUserInfo(userInfo);

    tolua_pushusertype_and_takeownership(L, new(std::nothrow)UserInfo(userInfo), USERTYPE_USERINFO);
    lua_pushinteger(L, err);
    return 2;
}

static int script_getScriptInfo(lua_State *L) {
    ScriptInfo scriptInfo;
    int err = Script::getInstance()->getScriptInfo(scriptInfo);

    tolua_pushusertype_and_takeownership(L, new(std::nothrow)ScriptInfo(scriptInfo),
                                         USERTYPE_SCRIPTINFO);
    lua_pushinteger(L, err);
    return 2;
}

static int script_getBillboard(lua_State *L) {
    return 0;
}

static int script_getUIData(lua_State *L) {
    return 0;
}

static int script_getResData(lua_State *L) {
    return 0;
}

static const luaL_Reg script_funcs[] = {
        {"__tostring",    script_tostring},
        {"getUserInfo",   script_getUserInfo},
        {"getScriptInfo", script_getScriptInfo},
        {"getBillboard",  script_getBillboard},
        {"getUIData",     script_getUIData},
        {"getResData",    script_getResData},
        {nullptr,         nullptr}
};

// UserInfo
int userinfo_destructor(lua_State *L) {
    UserInfo *self = (UserInfo *) tolua_tousertype(L, 1, 0);
    LOGV("UserInfo:destructor self:%p", self);
    SAFE_DELETE(self);
    return 0;
}

static int userinfo_tostring(lua_State *L) {
    lua_pushfstring(L, "class: %p", lua_topointer(L, 1));
    return 1;
}

static const luaL_Reg userinfo_funcs[] = {
        {"__tostring", userinfo_tostring},
        {nullptr,      nullptr}
};

static int get_UserInfo_id(lua_State *L) {
    UserInfo *self = (UserInfo *) toluahelper_tousertype(L, 1, USERTYPE_USERINFO, nullptr);
    if (!self) {
        tolua_error(L, "[no object] in field 'id'", nullptr);
    }

    lua_pushstring(L, self->getId().c_str());
    return 1;
}

static int get_UserInfo_membership(lua_State *L) {
    UserInfo *self = (UserInfo *) toluahelper_tousertype(L, 1, USERTYPE_USERINFO, nullptr);
    if (!self) {
        tolua_error(L, "[no object] in field 'membership'", nullptr);
    }

    lua_pushinteger(L, self->getMembership());
    return 1;
}

static int get_UserInfo_expiredTime(lua_State *L) {
    UserInfo *self = (UserInfo *) toluahelper_tousertype(L, 1, USERTYPE_USERINFO, nullptr);
    if (!self) {
        tolua_error(L, "[no object] in field 'expiredTime'", nullptr);
    }

    lua_pushinteger(L, self->getExpiredTime());
    return 1;
}

// ScriptInfo
int scriptinfo_destructor(lua_State *L) {
    ScriptInfo *self = (ScriptInfo *) tolua_tousertype(L, 1, 0);
    LOGV("ScriptInfo:destructor self:%p", self);
    SAFE_DELETE(self);
    return 0;
}

static int scriptinfo_tostring(lua_State *L) {
    lua_pushfstring(L, "class: %p", lua_topointer(L, 1));
    return 1;
}

static const luaL_Reg scriptinfo_funcs[] = {
        {"__tostring", scriptinfo_tostring},
        {nullptr,      nullptr}
};

static int get_ScriptInfo_id(lua_State *L) {
    ScriptInfo *self = (ScriptInfo *) toluahelper_tousertype(L, 1, USERTYPE_SCRIPTINFO, nullptr);
    if (!self) {
        tolua_error(L, "[no object] in field 'id'", nullptr);
    }

    lua_pushinteger(L, self->getId());
    return 1;
}

LUAMOD_API int luaopen_script(lua_State *L) {
    tolua_open(L);

    tolua_module(L, nullptr, 0);
    tolua_beginmodule(L, nullptr);
    {
        // Script
        tolua_usertype(L, USERTYPE_SCRIPT);
        tolua_cclass(L, CLASSNAME_SCRIPT, USERTYPE_SCRIPT, "", nullptr);

        tolua_beginmodule(L, CLASSNAME_SCRIPT);
        {
            toluahelper_setfunc(L, script_funcs);
        }
        tolua_endmodule(L);

        // UserInfo
        tolua_usertype(L, USERTYPE_USERINFO);
        tolua_cclass(L, CLASSNAME_USERINFO, USERTYPE_USERINFO, "", userinfo_destructor);

        tolua_beginmodule(L, CLASSNAME_USERINFO);
        {
            toluahelper_setfunc(L, userinfo_funcs);

            TOLUAHELPER_CLASS_CONST_VARIABLE_NS(L, UserInfo, id);
            TOLUAHELPER_CLASS_CONST_VARIABLE_NS(L, UserInfo, membership);
            TOLUAHELPER_CLASS_CONST_VARIABLE_NS(L, UserInfo, expiredTime);
        }
        tolua_endmodule(L);

        // ScriptInfo
        tolua_usertype(L, USERTYPE_SCRIPTINFO);
        tolua_cclass(L, CLASSNAME_SCRIPTINFO, USERTYPE_SCRIPTINFO, "", scriptinfo_destructor);

        tolua_beginmodule(L, CLASSNAME_SCRIPT);
        {
            toluahelper_setfunc(L, scriptinfo_funcs);

            TOLUAHELPER_CLASS_CONST_VARIABLE_NS(L, ScriptInfo, id);
        }
        tolua_endmodule(L);
    }
    tolua_endmodule(L);
    return 0;
}